// test_array.cpp -- test suite for Array


#include <cstdio>
#include <new>
#include <string>
#include <utility>

#include "array.hxx"


namespace blog
{


static
Array<int>
a_new_array()
{
    Array<int> a(7);
    a[0] = 10, a[1] = 11, a[2] = 12, a[3] = 13, a[4] = 14, a[5] = 15, a[6] = 16;
    return a;
}


static
void
test_array_default_constructor()
{
    std::printf("\n%70s\n", "[test_array_default_constructor]");
    Array<int> a(3);
    a[0] = 10, a[1] = 11, a[2] = 12, a[3] = 13;
    std::printf("a[0] = %d, a[2] = %d\n", a[0], a[2]);
}


static
void
test_array_initializer_constructor()
{
    std::printf("\n%70s\n", "[test_array_initializer_constructor]");
    Array<char> a({'a','b','c','d'});
    std::printf("a[1] = %c, a[3] = %c\n", a[1], a[3]);
}


static
void
test_array_copy_constructor()
{
    std::printf("\n%70s\n", "[test_array_copy_constructor]");
    Array<char> a({'x','y','z'});
    Array<char> b(a);
    Array<int> c ;
    c = a_new_array();
    std::printf("a[0] = %c, a[2] = %c\n", a[0], a[2]);
    std::printf("b[0] = %c, b[2] = %c\n", b[0], b[2]);
    std::printf("c[0] = %d, c[2] = %d\n", c[0], c[2]);
}


static
void
test_array_move_constructor()
{
    std::printf("\n%70s\n", "[test_array_move_constructor]");
    Array<int> a(5);
    a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4;
    Array<int> b = std::move(a);
    //std::printf("\na[0] = %d, a[4] = %d\n", a[0], a[4]);
    std::printf("b[0] = %d, b[4] = %d\n", b[0], b[4]);
}


static
void
test_array_copy_assign_operator()
{
    std::printf("\n%70s\n", "[test_array_copy_assign_operator]");
    Array<int> a(5);
    a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4;
    Array<int> b(5);
    b = a;
    std::printf("a[1] = %d, a[4] = %d\n", a[1], a[4]);
    std::printf("b[1] = %d, b[4] = %d\n", b[1], b[4]);
}


static
void
test_array_move_assign_operator()
{
    std::printf("\n%70s\n", "[test_array_move_assign_operator]");
    Array<int> a(5);
    a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4;
    Array<int> b(5);
    b = std::move(a);
    //std::printf("\na[1] = %d, a[4] = %d\n", a[1], a[4]);
    std::printf("b[1] = %d, b[4] = %d\n", b[1], b[4]);
}


static
void
test_array_shared()
{
    std::printf("\n%70s\n", "[test_array_shared]");
    Array<char> a({'a','b','c','d'});
    {
        Array<char> b(a);
        b[1] = 'x';
        Array<char> c(b);
        c[3] = 'z';
    }
    std::printf("a[1] = %c, a[2] = %c, a[3] = %c\n", a[1], a[2], a[3]);
}


static
void
test_array_rangedfor()
{
    std::printf("\n%70s\n", "[test_array_rangedfor]");
    Array<char> a({'a','b','c','d'});
    for (char x : a)
        std::printf("%2c", x);
    std::printf("\n");
}


} // end of namespace blog



int
main()
{

    blog::test_array_default_constructor(); std::printf("\n");

    blog::test_array_initializer_constructor(); std::printf("\n");

    blog::test_array_copy_constructor(); std::printf("\n");

    blog::test_array_move_constructor(); std::printf("\n");

    blog::test_array_copy_assign_operator(); std::printf("\n");

    blog::test_array_move_assign_operator(); std::printf("\n");

    blog::test_array_shared(); std::printf("\n");

    blog::test_array_rangedfor(); std::printf("\n");

    return 0;
}
